#include "stdafx.h"
#include "ctl_image_button.h"
#include "window_project.h"
#include "config.h"
#include "string_manager.h"

const image_button g_default_image_button;

void image_button::on_clone_attributes(control* aSrc)
{
	__super::on_clone_attributes(aSrc);

	image_button * pSrc = (image_button *)aSrc;

	m_strText		= pSrc->m_strText;
	m_strSaveText	= pSrc->m_strSaveText;
	m_imageExclude	= pSrc->m_imageExclude;
	m_verticalImage = pSrc->m_verticalImage;	
	m_strImageString= pSrc->m_strImageString;
	m_strImgFileName= pSrc->m_strImgFileName;
	m_imageRect		= pSrc->m_imageRect;	
	m_image			= NULL;
	set_image_file(m_strImageString);
}

bool image_button::load(IXMLDOMNode* aXmlNode)
{
	if (!__super::load(aXmlNode))
	{
		return false;
	}

	return true;
}

bool image_button::save(IXMLDOMNode* aXmlNode)
{
	IXMLDOMElement*		pXmlElement = (IXMLDOMElement*) aXmlNode;

	if (m_strSaveText.length() <= 0)
	{
		m_strSaveText = m_strText;
	}
	if (m_strSaveText != g_default_image_button.m_strSaveText&& 
		(!m_pReference || !m_pReference->exist_property(L"text") || 
		m_pReference->get_property(L"text") != m_strSaveText))
	{
		pXmlElement->setAttribute(L"text",		(_variant_t)m_strSaveText.c_str());
	}

	if (m_strImageString != g_default_image_button.m_strImageString&& 
		(!m_pReference || !m_pReference->exist_property(L"image") || 
		m_pReference->get_property(L"image") != m_strImageString))
	{
		pXmlElement->setAttribute(L"image",		(_variant_t)m_strImageString.c_str());
	}

	rect tempRect;
	if (m_imageExclude != g_default_image_button.m_imageExclude && 
		(!m_pReference || !m_pReference->exist_property(L"image_exclude") || 
		!load_helper::parse_rect(m_pReference->get_property(L"image_exclude"), tempRect) ||
		tempRect != m_imageExclude))
	{
		pXmlElement->setAttribute(L"image_exclude",		(_variant_t)load_helper::to_string(m_imageExclude).c_str());
	}

	bool tmpBool;
	if (m_verticalImage != g_default_image_button.m_verticalImage && 
		(!m_pReference || !m_pReference->exist_property(L"vertical_image") || 
		!load_helper::parse_bool(m_pReference->get_property(L"vertical_image"), tmpBool) ||
		tmpBool != m_verticalImage))
	{
		pXmlElement->setAttribute(L"vertical_image",		(_variant_t)load_helper::to_string(m_verticalImage).c_str());
	}
	return true;
}

void image_button::render(Graphics & aGraphics)
{
	float x,y,w = (float)m_size.width, h = (float)m_size.height;

	point abPt = get_absolute_pos();	

	if (m_image)
	{
		int iState = 0;
		if (m_verticalImage)
		{
			w = (float)m_imageRect.width();
			h = (float)m_imageRect.height()/4;
			x = (float)m_imageRect.left;
			y = (float)m_imageRect.top + iState*h;
		}else
		{
			w = (float)m_imageRect.width()/4;
			h = (float)m_imageRect.height();
			x = (float)m_imageRect.left + iState*w;
			y = (float)m_imageRect.top;
		}

		w -= m_imageExclude.left + m_imageExclude.right;
		h -= m_imageExclude.top + m_imageExclude.bottom;
		x += m_imageExclude.left;
		y += m_imageExclude.top;

		point p = get_absolute_pos();

		aGraphics.DrawImage(m_image, get_absolute_rect(), x, y, w, h, UnitPixel);
	}
	
	if (m_strText.length() > 0)
	{
		SolidBrush sb(m_clrTextColor);
		StringFormat sf;
		sf.SetAlignment(Gdiplus::StringAlignmentCenter);
		Gdiplus::Font* font = font_manager::get_font(L"face", 1);
		int textHeight = (int)font->GetHeight(&aGraphics);
		rect rt = get_absolute_rect();
		rt.bottom = rt.top + (int)h;
		int trip = (int)(h - textHeight)/2;
		rt.top += trip;
		aGraphics.DrawString(m_strText.c_str(), m_strText.length(), 
			font, rt, &sf, &sb);
	}	
}

void image_button::set_image_file(wstring aStrFileName)
{
	m_strImageString = aStrFileName;

	if (m_image)
	{
		delete m_image;
	}

	int spPos = aStrFileName.find_first_of(L'|');

	m_strImgFileName = aStrFileName;
	wstring rectStr  = aStrFileName;
	if (wstring::npos != spPos)
	{
		m_strImgFileName = m_strImgFileName.erase(spPos);
		rectStr = rectStr.erase(0, spPos + 1);	
		load_helper::parse_rect(rectStr, m_imageRect);
	}

	wstring strTmpPath = path_helper::process_file(m_strImgFileName, m_belongTo->get_file_name());
	m_image = new Gdiplus::Image(strTmpPath.c_str(), FALSE);
	m_strImgFileName = strTmpPath;
}

void image_button::add_attribute(wstring aStrName, wstring aStrValue)
{
	if (aStrName.compare(L"image") == 0)
	{
		set_image_file(aStrValue);
		return;
	}

	if (aStrName.compare(L"image_exclude") == 0)
	{
		if (!load_helper::parse_rect(aStrValue, m_imageExclude))
		{
			return;
		}
		return;
	}

	if (aStrName.compare(L"text") == 0)
	{
		m_strSaveText = aStrValue;

		m_strText = string_manager::m_s_sm.get_string(aStrValue);
		if (m_strText.length() <= 0)
		{
			m_strText = m_strSaveText;
		}
		return;
	}

	if (aStrName.compare(L"vertical_image") == 0)
	{
		if (!load_helper::parse_bool(aStrValue, m_verticalImage))
		{
			return;
		}
		return;
	}

	__super::add_attribute(aStrName, aStrValue);
}

void image_button::build_properties()
{
	__super::build_properties();

	CMFCPropertyGridProperty* group = NULL;
	CMFCPropertyGridProperty* property = NULL;
	group = m_Properties.alloc_group(this, L"image_button");

	property = m_Properties.alloc_property_normal(this, L"text", (_variant_t)m_strText.c_str());
	property->SetValue((_variant_t)(wchar_t*)m_strText.c_str());
	group->AddSubItem(property);

	property = m_Properties.alloc_property_normal(this, L"image", (_variant_t)m_strImgFileName.c_str());
	property->SetValue((_variant_t)(wchar_t*)m_strImgFileName.c_str());
	group->AddSubItem(property);

	m_Properties.add_property(group);
}

s_properties& image_button::get_properties()
{
	__super::get_properties();

	CMFCPropertyGridProperty* prop = NULL;
	prop = m_Properties.find_by_name(L"text");
	if (prop)
	{
		prop->SetValue((_variant_t)m_strText.c_str());
	}

	prop = m_Properties.find_by_name(L"image");
	if (prop)
	{
		prop->SetValue((_variant_t)m_strImgFileName.c_str());
	}

	return m_Properties;
}

void image_button::on_property_changed(CMFCPropertyGridProperty* aProperty)
{
	wstring strOldValue;
	wstring strNewValue;


	const wchar_t* strName = aProperty->GetName();
	if (wcscmp(strName, L"text") == 0)
	{
		strOldValue = m_strSaveText;
		add_attribute(L"text", aProperty->GetValue().bstrVal);
		strNewValue = m_strSaveText;
	}else if (wcscmp(strName, L"image") == 0)
	{
		strOldValue = m_strImageString;
		set_image_file(aProperty->GetValue().bstrVal);
		strNewValue = m_strImageString;
	}else
	{
		__super::on_property_changed(aProperty);
		return;
	}

	op_modify_ctl* op = new op_modify_ctl(this, wstring((wchar_t*)strName), strOldValue, strNewValue);
	if (m_belongTo)
	{
		m_belongTo->m_undoRedo.operation(op);
	}else
		delete op;

	if (m_belongTo)
	{
		m_belongTo->refrash();
	}
}